package com.guang.springbootexception.restful;

import com.guang.springbootexception.exception.ServiceException;
import com.guang.springbootexception.exception.ServiceExceptions;
import com.guang.springbootexception.utils.StringUtil;
import lombok.Data;

import java.util.List;
import java.util.Map;

/**
 * 相应实体类信息
 * @param <T>
 */
@Data
public final class RestHttpEntity<T> {
    /**
     * 相应状态码
     */
    private Integer code;
    /**
     * 响应信息
     */
    private String msg;
    /**
     * 请求状态
     */
    private Boolean success;
    /**
     * 序列化号
     */
    private String serialNo;
    /**
     * 响应的数据包装类
     */
    private RestData<T> data;

    public RestPage pageForRequest() throws ServiceException {
        this.validateData();
        this.validatePage();
        return this.data.getPage();
    }

    public T bodyForRequest() throws ServiceException {
        this.validateData();
        this.validateBody();
        return this.data.getBody();
    }

    public RestPage pageForResponse(String errMsg) throws ServiceException {
        errMsg = StringUtil.isBlank(errMsg) ? "未知异常" : errMsg;
        this.validateHeader(errMsg);
        this.validateData();
        this.validatePage();
        return this.data.getPage();
    }

    public T bodyForResponse(String errMsg) throws ServiceException {
        errMsg = StringUtil.isBlank(errMsg) ? "未知异常" : errMsg;
        this.validateHeader(errMsg);
        this.validateData();
        this.validateBody();
        return this.data.getBody();
    }

    /**
     * 根据对应的code来构建异常信息
     * @param errMsg
     * @throws ServiceException
     */
    private void validateHeader(String errMsg) throws ServiceException {
        if (this.code == null || !ServiceExceptions.SSSS.getErrCode().equals(this.code)) {
            errMsg = StringUtil.isBlank(this.msg) ? errMsg : this.msg;
            ServiceExceptions serviceExceptions = ServiceExceptions.findServiceExceptions(this.code);
            throw serviceExceptions == null ? ServiceExceptions.F999.buildServiceException(errMsg) : serviceExceptions.buildServiceException(errMsg);
        }
    }

    /**
     * 报文校验
     * @throws ServiceException
     */
    private void validateData() throws ServiceException {
        if (this.data == null) {
            throw ServiceExceptions.F999.buildServiceException("报文data为空");
        }
    }

    /**
     * 分页信息校验
     * @throws ServiceException
     */
    private void validatePage() throws ServiceException {
        if (this.data == null || this.data.getPage() == null) {
            throw ServiceExceptions.F999.buildServiceException("报文data.page为空");
        }
    }

    /**
     * 校验响应体
     * @throws ServiceException
     */
    private void validateBody() throws ServiceException {
        if (this.data == null || this.data.getBody() == null) {
            throw ServiceExceptions.F999.buildServiceException("报文data.body为空");
        }
    }

    public static <T> RestHttpEntity<T> buildRequest(T body) {
        RestHttpEntity<T> request = new RestHttpEntity();
        RestData data = new RestData();
        data.setBody(body);
        request.setData(data);
        return request;
    }

    public static <T> RestHttpEntity<T> buildRequest(String serialNo, T body) {
        RestHttpEntity<T> request = new RestHttpEntity();
        request.setSerialNo(serialNo);
        RestData data = new RestData();
        data.setBody(body);
        request.setData(data);
        return request;
    }

    public static <T> RestHttpEntity<T> buildSuccessResponse() {
        RestHttpEntity<T> response = new RestHttpEntity();
        response.setCode(ServiceExceptions.SSSS.getErrCode());
        response.setMsg(ServiceExceptions.SSSS.getErrMsg());
        return response;
    }

    public static <T> RestHttpEntity<T> buildSuccessResponse(T body) {
        RestHttpEntity<T> response = new RestHttpEntity();
        response.setCode(ServiceExceptions.SSSS.getErrCode());
        response.setMsg(ServiceExceptions.SSSS.getErrMsg());
        RestData<T> restData = new RestData();
        restData.setBody(body);
        response.setData(restData);
        return response;
    }

    public static <T> RestHttpEntity<Map<String, T>> buildSuccessResponse(Map<String, T> body) {
        RestHttpEntity<Map<String, T>> response = new RestHttpEntity();
        response.setCode(ServiceExceptions.SSSS.getErrCode());
        response.setMsg(ServiceExceptions.SSSS.getErrMsg());
        RestData<Map<String, T>> restData = new RestData();
        restData.setBody(body);
        response.setData(restData);
        return response;
    }

    public static <T> RestHttpEntity<List<T>> buildSuccessResponse(List<T> body) {
        RestHttpEntity<List<T>> response = new RestHttpEntity();
        response.setCode(ServiceExceptions.SSSS.getErrCode());
        response.setMsg(ServiceExceptions.SSSS.getErrMsg());
        RestData<List<T>> restData = new RestData();
        restData.setBody(body);
        response.setData(restData);
        return response;
    }

    public static <T> RestHttpEntity<List<T>> buildSuccessResponse(RestPage page, List<T> body) {
        RestHttpEntity<List<T>> response = new RestHttpEntity();
        response.setCode(ServiceExceptions.SSSS.getErrCode());
        response.setMsg(ServiceExceptions.SSSS.getErrMsg());
        RestData<List<T>> restData = new RestData();
        restData.setPage(page);
        restData.setBody(body);
        response.setData(restData);
        return response;
    }

    /**
     * 即使是失败了，也是一个正确的请求，应该是被正确响应了，所以这里应该来做一个理性的判断而已。
     * @param serviceException
     * @param <T>
     * @return
     */
    public static <T> RestHttpEntity<T> buildFailResponse(ServiceException serviceException) {
        RestHttpEntity<T> response = new RestHttpEntity();
        response.setCode(serviceException.getErrCode());
        response.setMsg(serviceException.getErrMsg());
        return response;
    }

    public RestHttpEntity() {
        this.success = Boolean.TRUE;
    }
}